/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import React, {useState, useRef} from 'react';
import {
  View,
  Text,
  Image,
  TouchableOpacity,
  StyleSheet,
  Dimensions,
  Animated,
} from 'react-native';

import PlaylistHeader from './PlaylistHeader';
import {songs, Track} from '../model';
import CurPlaySong from './CurPlaySong';

import {useBreakpointValue} from '@hadss/react_native_adaptive_layout/src/hooks/useBreakpointValue';
import musicPlayer from '../../util';
import SampleTurboModule from '../../basic/SampleTurboModule';
import {
  Menu,
  MenuOptions,
  MenuOption,
  MenuTrigger,
  MenuProvider,
} from 'react-native-popup-menu';
import {
  GestureHandlerRootView,
  PanGestureHandler,
  State,
  TapGestureHandler,
} from '@react-native-oh-tpl/react-native-gesture-handler';
import {PlayListPage} from '../../util/constants.tsx';

const {height} = Dimensions.get('window');

const SongList = () => {
  const translateY = useRef(new Animated.Value(0)).current;
  const [songsList, setSongsList] = useState(songs);
  const [currentSong, setCurrentSong] = useState<Track>(songs[0]);
  const [isPlaying, setIsPlaying] = useState(false);
  let itemWidth = useBreakpointValue({
    base: Dimensions.get('window').width - 32,
    sm: Dimensions.get('window').width - 32,
    md: Dimensions.get('window').width - 72,
  });

  // 若是长按时候，阻止单击或双击事件
  const [isLongPressed, setIsLongPressed] = useState(false);
  // 删除数据()
  const deleteItem = (index: number) => {
    setSongsList(songsList =>
      songsList.filter((_item, index1) => index1 !== index),
    );
  };

  // 收藏数据
  const collectItem = (index: number) => {
    setSongsList(songsList =>
      songsList.map((item1, index1) =>
        index1 == index ? {...item1, hasCollect: true} : item1,
      ),
    );
  };
  // 取消收藏数据
  const deleteCollectItem = (index: number) => {
    setSongsList(songsList =>
      songsList.map((item1, index1) =>
        index1 == index ? {...item1, hasCollect: false} : item1,
      ),
    );
  };
  const lastOffset = useRef({y: 0}).current;
  // 清扫和滚动--start
  const [currentIndex, setCurrentIndex] = useState(0);

  const onPanGestureEvent = Animated.event(
    [{nativeEvent: {translationY: translateY}}],
    {useNativeDriver: true},
  );

  const onHandlerStateChange = (event: any) => {
    const {translationY, velocityY} = event.nativeEvent;
    if (
      Math.abs(translationY) > PlayListPage.SWIPE_THRESHOLD &&
      Math.abs(velocityY) > PlayListPage.VELOCITY_THRESHOLD
    ) {
      // 获取当前位置
      let targetIndex = currentIndex;
      let targetOffset = 0;
      // 向上轻扫
      if (translationY < 0) {
        targetIndex = Math.min(currentIndex + 10, songs.length - 9);
        targetOffset = -10 * PlayListPage.ITEM_HEIGHT + lastOffset.y;
      } else if (translationY > 0) {
        // 向下轻扫
        targetIndex = Math.max(currentIndex - 10, 0);
        targetOffset = 10 * PlayListPage.ITEM_HEIGHT + lastOffset.y;
      }
      // 若是已经到页面的头部，不允许继续上滑动了
      if (targetOffset > 0 || targetIndex == 0) {
        targetOffset = 0;
      }
      // 若是已经到页面的底部，不允许继续下滑动了
      if (targetIndex >= songs.length - 10) {
        targetOffset = -(songs.length - 9) * PlayListPage.ITEM_HEIGHT;
      } else {
        setCurrentIndex(targetIndex);
      }
      // 动画到目标位置
      Animated.spring(translateY, {
        toValue: targetOffset,
        useNativeDriver: true,
        velocity: event.nativeEvent.velocityY,
      }).start();
      lastOffset.y = targetOffset;
      translateY.setOffset(targetOffset);
      translateY.setValue(0);
    } else {
      if (event.nativeEvent.state === State.END) {
        let newOffset = lastOffset.y + event.nativeEvent.translationY;
        // 设置上边界
        const maxOffset = 0;
        // 设置下边界（根据内容高度计算）
        const minOffset = -((songs.length - 9) * PlayListPage.ITEM_HEIGHT);
        let newOffset1 = Math.min(maxOffset, Math.max(minOffset, newOffset));
        lastOffset.y = newOffset1;
        translateY.setOffset(lastOffset.y);
        translateY.setValue(0);
        // 若是滚动之后出现轻扫，需要设置轻扫的初始位置
        setCurrentIndex(Math.ceil(-lastOffset.y / PlayListPage.ITEM_HEIGHT));
      }
    }
  };
  //列表上的当双击事件---start
  // 记录上次点击时间，用于区分单击和双击
  let lastTap = 0;
  let timerId: any;
  const onHandlerStateChangeForList = (event: any, songID: string) => {
    if (event.nativeEvent.state === State.ACTIVE) {
      const currentTime = Date.now();
      const delta = currentTime - lastTap;
      // 如果两次点击时间差小于300ms，则认为是双击
      if (delta < 300) {
        SampleTurboModule.pushStringToHarmony('pages/MusicPlay', 1);
        musicPlayer.playTrackByIndex(songID, true);
        clearTimeout(timerId);
      } else {
        // 否则延迟300ms执行单击事件
        // 这是为了等待可能的第二次点击
        timerId = setTimeout(() => {
          if (Date.now() - lastTap > 300) {
            SampleTurboModule.pushStringToHarmony('pages/MusicPlay', 1);
            musicPlayer.playTrackByIndex(songID, false);
          }
        }, 300);
      }
      lastTap = currentTime;
    }
  };

  // 在点击列表后面的：的时候，获取点击位置给上下文组件
  const [position, setPosition] = useState({top: 0, left: 0});
  const calculateMenuPosition = (event: any) => {
    setPosition({
      top: event.nativeEvent.pageY + 10,
      left: event.nativeEvent.pageX - 50,
    });
  };

  //列表上的当双击事件---end
  const renderItem = (item: Track, index: number) => (
    <GestureHandlerRootView>
      <TapGestureHandler
        onHandlerStateChange={event =>
          onHandlerStateChangeForList(event, item.songID)
        }
        numberOfTaps={1}
        enabled={!isLongPressed}>
        <TouchableOpacity style={[styles.songItem, {width: itemWidth}]}>
          <View style={styles.songInfo}>
            <View style={styles.songInfoInner}>
              <Text style={styles.songTitle}>{item.title}</Text>
              {item.hasCollect ? (
                <Image
                  source={require('../../../../asset/music_love.svg')}
                  style={styles.liveIcon}
                />
              ) : (
                ''
              )}
            </View>
            <View style={styles.vipStyle}>
              {item.isVip ? <Text style={styles.songVIP}>VIP</Text> : ''}
              {item.audioType ? (
                <Text style={styles.songAudioType}>{item.audioType}</Text>
              ) : (
                ''
              )}
              <Text style={styles.songArtist}>{item.artist}</Text>
            </View>
          </View>
          <View style={{flex: 1}} />
          <View
            style={{alignItems: 'center', marginTop: 20}}
            onTouchStart={calculateMenuPosition}>
            <Menu
              onClose={() => {
                setTimeout(() => setIsLongPressed(false), 500);
              }}>
              <MenuTrigger
                triggerOnLongPress={true}
                onPress={() => {
                  setIsLongPressed(true);
                }}>
                <Image
                  source={require('../../../../asset/song_item_icon.svg')}
                  style={styles.songIcon}
                />
              </MenuTrigger>
              <MenuOptions
                optionsContainerStyle={[
                  styles.optionList,
                  {
                    position: 'absolute',
                    top: position.top,
                    left: position.left,
                  },
                ]}>
                <MenuOption
                  onSelect={() => deleteItem(index)}
                  style={{flexDirection: 'row'}}>
                  <Image
                    source={require('../../../../asset/delete.svg')}
                    style={styles.songDelete}
                  />
                  <Text style={styles.optionBtn}>{'删除'}</Text>
                </MenuOption>
                {item.hasCollect ? (
                  <MenuOption
                    onSelect={() => deleteCollectItem(index)}
                    style={{flexDirection: 'row'}}>
                    <Image
                      source={require('../../../../asset/deleteCollect.svg')}
                      style={styles.songDelete}
                    />
                    <Text style={styles.optionBtn}>{'移除收藏'}</Text>
                  </MenuOption>
                ) : (
                  <MenuOption
                    onSelect={() => collectItem(index)}
                    style={{flexDirection: 'row'}}>
                    <Image
                      source={require('../../../../asset/collect.svg')}
                      style={styles.songDelete}
                    />
                    <Text style={styles.optionBtn}>{'收藏到歌单'}</Text>
                  </MenuOption>
                )}
              </MenuOptions>
            </Menu>
          </View>
        </TouchableOpacity>
      </TapGestureHandler>
    </GestureHandlerRootView>
  );
  return (
    <MenuProvider style={{flex: 1, backgroundColor: 'rgb(239, 239, 239)'}}>
      <GestureHandlerRootView style={{flex: 1, overflow: 'hidden'}}>
        <PanGestureHandler
          onGestureEvent={onPanGestureEvent}
          onHandlerStateChange={onHandlerStateChange}>
          <Animated.View style={[{transform: [{translateY: translateY}]}]}>
            <View
              style={{
                width: '100%',
                height: 150,
              }}>
              {<PlaylistHeader />}
            </View>
            {songsList.map((item, index) => (
              <View key={index} style={styles.item}>
                {renderItem(item, index)}
              </View>
            ))}
          </Animated.View>
        </PanGestureHandler>
      </GestureHandlerRootView>
      <CurPlaySong
        song={currentSong}
        setCurrentSong={setCurrentSong}
        isPlaying={isPlaying}
        setIsPlaying={setIsPlaying}
      />
    </MenuProvider>
  );
};

const styles = StyleSheet.create({
  songItem: {
    flexDirection: 'row',
    height: 64,
    alignItems: 'center',
  },
  songInfo: {
    flexDirection: 'column',
    justifyContent: 'center',
  },
  songTitle: {
    fontSize: 16,
    fontWeight: '500',
    lineHeight: 21,
    color: PlayListPage.color2,
  },
  songArtist: {
    fontSize: 12,
    color: PlayListPage.color3,
    lineHeight: 16,
  },
  songVIP: {
    color: PlayListPage.color4,
    fontSize: 10,
    lineHeight: 16,
    height: 16,
    backgroundColor: PlayListPage.color1,
    borderRadius: 4,
    marginRight: 8,
    verticalAlign: 'middle',
    paddingHorizontal: 4,
  },
  songAudioType: {
    color: PlayListPage.color4,
    fontSize: 10,
    lineHeight: 16,
    height: 16,
    backgroundColor: PlayListPage.color1,
    borderRadius: 4,
    marginRight: 8,
    verticalAlign: 'middle',
    paddingHorizontal: 4,
  },
  songIcon: {
    width: 20,
    color: PlayListPage.color3,
    height: 20,
  },
  acoustic: {
    width: 16,
    height: 16,
  },
  list: {
    paddingBottom: height + PlayListPage.ITEM_HEIGHT * 13, // 确保可以滚动到底部
  },
  item: {
    height: PlayListPage.ITEM_HEIGHT,
    justifyContent: 'center',
    paddingLeft: 16,
    borderBottomWidth: 1,
    borderBottomColor: '#eee',
  },
  optionList: {
    width: 150,
    borderRadius: 20,
    paddingVertical: 4,
    paddingHorizontal: 16,
    color: PlayListPage.color2,
  },
  songDelete: {
    width: 12,
    height: 14,
    lineHeight: 14,
    verticalAlign: 'middle',
    marginRight: 6,
  },
  optionBtn: {
    width: 150,
    fontSize: 16,
    fontWeight: 500,
  },
  songInfoInner: {
    flexDirection: 'row',
    top: 2,
    alignItems: 'center',
  },
  liveIcon: {
    width: 16,
    height: 14,
    marginLeft: 10,
  },
  vipStyle: {
    flexDirection: 'row',
    top: 2,
  },
});

export default SongList;
